/*

Copyright (C) 2007 Manfred Gschweidl (manfred.gschweidl@students.fhv.at)

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

*/


#ifndef GGRAMJOBCALLBACK_H_
#define GRAMJOBCALLBACK_H_

#include <cstdio>
#include <string>
#include <map>

#include "globus_gram_client.h"
#include "globus_gram_protocol.h"
#include "globus_gss_assist.h"

#include "URL.h"
#include "Callback.h"

using namespace std;
using namespace globus_common;

namespace globus_job {

class GramJobCallback;
class GramJob;

/**
 * Generic gram job callback manager, able to handle more than one job
 */
class GramJobCallback {
	private:
		globus_mutex_t				JobsTableMutex;
		/* This is the identifier for the callback, returned by
		globus_gram_job_request */
		char*						callback_contact;
		//jobs map, key jobcontact
		map<string,GramJob*>	JobsTable;
		//functions
		void lock();
		void unLock();
	public:
		GramJobCallback();
		~GramJobCallback();
		/**
		 * Add a job to the manager
		 */
		void add(string,GramJob*);
		/**
		 * Remove a job from tje manager
		 */
		void remove(char*);
		/** 
		 * Get managers contact url
		 */
		char* getURL();
		/**
		 * Get job identified by jobcontact
		 */
		GramJob* getJob(char*);
};

/**
 * GRAM Job
 */
class GramJob { //: public Callback {
	private:
		//job contact and identifier returned by
		//callback function from globus
		char*					jobcontact;
		//mutex
		globus_mutex_t			jobcontactmutex;
		//job failed?
		bool					failed;
		//pointer to callback manager
		GramJobCallback*	callback;
		//flag for only waiting until got jobcontact
		bool					only_get_jobHandle;
		// the attribute
		globus_gram_client_attr_t attr;
		// cred
		gss_cred_id_t			credential;
		
 		globus_mutex_t mutex;
		globus_cond_t cond;
		globus_bool_t done;
		
	public:
		GramJob( GramJobCallback* );
		GramJob( GramJobCallback*, string );
		GramJob( string );
		~GramJob();
		/**
		 * Submit job (host, rsl)
		 */
		bool submit(string,string);
		/**
		 * Cancel job
		 */
		bool cancel();
		/**
		 * Set jobcontact - used by callback manager
		 */
		void setJobContact(const char*);
		/**
		 * Set job status failed
		 */
		void setFailed();
		/** 
		 * Check for a failed job
		 */
		bool hasFailed();
		/**
		 * Get jobcontact string as returned by globus
		 */
		string getJobContact();
		/** 
		 * Check whether background job submission is enabled
		 */
		bool onlyGetJobHandle();
		/**
		 * Enable/disable background job submission
		 */
		void setOnlyGetJobHandle(bool);
		/**
		 * Get status of the job from globus - blocking call
		 */
		int getJobStatus();		
		/** 
		 * Prints a user friendly job status message
		 */
		static string printJobStatus(int);
		/**
		 * Check for availability of gram server
		 */
		bool ping(URL* host);
		
		globus_bool_t isDone();
		/**
		 * finished
		 */
    	virtual void setDone();
    	/**
    	 * continue
    	 */ 
    	virtual void proceed();
    	/**
    	 * wait for condition
    	 */
		virtual void wait(); 
};

}

#endif /*GRAMJOBSCALLBACK_H_*/
